#include "TCPChannel.h"
#include <cmath>
#include <cstring>
#include <cstdlib>

extern "C"
{
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
}

namespace qy
{

TCPChannel::TCPChannel(int socket)
: m_socket(socket)
{
}

TCPChannel::~TCPChannel()
{
	close();
}

void TCPChannel::close()
{
	::close(m_socket);
}

bool TCPChannel::canSend(double timeout)
{
	fd_set fds;
	struct timeval tv;
	if(m_socket < 0)
	{
		return false;
	}

	FD_ZERO(&fds);
	FD_SET(m_socket, &fds);

	tv.tv_sec = floor(timeout);
	tv.tv_usec = (timeout - tv.tv_sec) * 100000;

	if(::select(m_socket + 1, NULL, &fds, NULL, &tv) > 0)
	{
		return FD_ISSET(m_socket, &fds);
	}
	return false;
}

bool TCPChannel::canReceive(double timeout)
{
	fd_set fds;
	struct timeval tv;
	if(m_socket < 0)
	{
		return false;
	}

	FD_ZERO(&fds);
	FD_SET(m_socket, &fds);

	tv.tv_sec = floor(timeout);
	tv.tv_usec = (timeout - tv.tv_sec) * 100000;

	if(::select(m_socket + 1, &fds, NULL, NULL, &tv) > 0)
	{
		return FD_ISSET(m_socket, &fds);
	}
	return false;
}

int TCPChannel::send(const char *data, int size)
{
	return ::send(m_socket, data, size, 0);
}

int TCPChannel::receive(char *buffer, int size)
{
	return recv(m_socket, buffer, size, 0);
}

}
